package pkemonyc.util;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 孵蛋器类（核心逻辑实现）
 * @Classname Incubator
 * @Date 2025/2/10 23:22
 * @Created by 87766867@qq.com
 */
public class Incubator {
    private static final Random rand = new Random();
    private static final double BASE_SHINY_RATE = 1.0 / 4096;
    // 新增性别比例数据源（示例数据）
    private static final Map<String, Double> GENDER_RATIOS = new HashMap<>();

    // 熏香对应表（亲代 -> 需要熏香 -> 子代）
    private static final Map<String, String> INCENSE_SPECIES = new HashMap<>();
    static {
        // 示例数据（需扩展完整官方数据）
        INCENSE_SPECIES.put("Marill@SeaIncense", "Azurill");
        INCENSE_SPECIES.put("Wobbuffet@LaxIncense", "Wynaut");
        INCENSE_SPECIES.put("Roselia@RoseIncense", "Budew");
        INCENSE_SPECIES.put("Marowak@RockIncense", "Cubone");
    }

    // 基础进化链（亲代 -> 子代）
    private static final Map<String, String> BASE_SPECIES = new HashMap<>();
    static {
        // 示例数据（需扩展完整进化链）
        BASE_SPECIES.put("Pikachu", "Pichu");
        BASE_SPECIES.put("Jynx", "Smoochum");
        BASE_SPECIES.put("Chansey", "Happiny");
    }

    /**
     * 完整性别生成逻辑（基于子代物种）
     * @param baby 子代宝可梦
     * @param species 子代物种名称
     */
    private void determineGender(Pokemon baby, String species) {
        String upperSpecies = species.toUpperCase();
        Double ratio = GENDER_RATIOS.getOrDefault(upperSpecies, 50.0);

        if (ratio == -1.0) {
            baby.gender = Pokemon.Gender.GENDERLESS;
            return;
        }

        if (ratio == 0.0) {
            baby.gender = Pokemon.Gender.FEMALE;
            return;
        }

        if (ratio == 100.0) {
            baby.gender = Pokemon.Gender.MALE;
            return;
        }

        // 精确概率计算（使用SecureRandom）
        double roll = rand.nextDouble() * 100;
        baby.gender = (roll < ratio) ? Pokemon.Gender.MALE : Pokemon.Gender.FEMALE;
    }
    /**
     * 生成宝可梦蛋（主入口方法）
     * @param parent1 父母1
     * @param parent2 父母2
     * @return 生成的蛋对象，无法生成时返回null
     */
    public Egg generateEgg(Pokemon parent1, Pokemon parent2) {
        // 步骤1：基础校验
        if (!validateParents(parent1, parent2)) {
            //效验错误
          System.out.println("无法生成蛋：无效的亲代");
          return null;
        };

        // 步骤2：创建子代对象
        Pokemon baby = new Pokemon(
                determineSpecies(parent1, parent2),
                new Pokemon.EggGroup[0], // 蛋组由物种决定
                Pokemon.Gender.GENDERLESS, // 临时值
                new int[6],
                false,
                false,
                "CHS",
                Pokemon.BallType.POKE_BALL,
                Pokemon.Nature.HARDY,
                new IncubationItems(false,false,false,false,false)
        );

        // 步骤3：遗传属性处理
        //个体值遗传
        inheritIVs(baby, parent1, parent2);
        //性格遗传
        inheritNature(baby, parent1, parent2);
        //特性遗传
        inheritAbility(baby, parent1, parent2);
        //球种遗传
        inheritBall(baby, parent1, parent2);
        determineGender(baby, parent1.species);

        // 步骤4：特殊属性生成
        baby.isShiny = calculateShiny(parent1, parent2);
        baby.form = determineForm(parent1, parent2);

        // 步骤5：遗传招式
        List<String> moves = inheritMoves(parent1, parent2);

        // 步骤6：计算孵化步数
        int steps = calculateSteps(parent1, parent2);

        return new Egg(baby, steps, moves);
    }

    /**
     * 确定子代物种（核心逻辑）
     * @param p1 父母1
     * @param p2 父母2
     * @return 子代物种名称
     */
    private String determineSpecies(Pokemon p1, Pokemon p2) {
        // 1. 确定亲代参考对象
        Pokemon mother = getMother(p1, p2);
        Pokemon father = (mother == p1) ? p2 : p1;

        // 2. 处理百变怪情况
        if (mother.isDitto) mother = father; // 百变怪不能作为母方参考
        if (father.isDitto) father = mother;
        // 3. 检查熏香效果
        String incenseKey = checkIncenseEffect(mother,father);
        if (incenseKey != null) {
            return INCENSE_SPECIES.get(incenseKey);
        }

        // 4. 基础进化链判断
        String baseSpecies = BASE_SPECIES.get(mother.species);
        return (baseSpecies != null) ? baseSpecies : mother.species;
    }
    /**
     * 检测熏香效果
     * @param mother 母方宝可梦
     * @return 熏香匹配键 或 null
     * https://www.bilibili.com/opus/633040443934769218
     */
    private String checkIncenseEffect(Pokemon mother, Pokemon father) {
        IncubationItems mother_items=mother.getHeldItems();
        IncubationItems father_items=father.getHeldItems();
        if (!mother_items.incense&&!father_items.incense){
            return null;
        }
        // 构建熏香检测键（例如："Marill@SeaIncense"）
        String key = mother.species + "@" + getIncenseType(mother);
        return INCENSE_SPECIES.containsKey(key) ? key : null;
    }

    /**
     * 获取熏香类型（需扩展完整逻辑）
     */
    private String getIncenseType(Pokemon p) {
        // 实际应检查携带物品字段
        // 这里简化为检测已知类型
        switch (p.species) {
            case "Marill": return "SeaIncense";
            case "Wobbuffet": return "LaxIncense";
            // 其他情况...
            default: return "Unknown";
        }
    }

    // region 校验逻辑
    /**
     * 验证父母合法性
     */
    private boolean validateParents(Pokemon p1, Pokemon p2) {
        // 检查未发现组
        if (hasUndiscoveredGroup(p1))
            return false;
        if (hasUndiscoveredGroup(p2))
            return false;

        // 检查蛋组兼容性
        return checkEggGroups(p1, p2) && checkGenderCompatibility(p1, p2);
    }

    /**
     * 检查是否存在未发现组
     */
    private boolean hasUndiscoveredGroup(Pokemon p) {
        return Arrays.asList(p.eggGroups).contains(Pokemon.EggGroup.UNDISCOVERED);
    }

    /**
     * 检查蛋组是否匹配（处理百变怪情况）
     */
    private boolean checkEggGroups(Pokemon p1, Pokemon p2) {
        // 百变怪逻辑
        if (p1.isDitto != p2.isDitto) {
            Pokemon nonDitto = p1.isDitto ? p2 : p1;
            return !hasUndiscoveredGroup(nonDitto);
        }

        // 普通蛋组匹配
        return Arrays.stream(p1.eggGroups)
                .anyMatch(g -> Arrays.asList(p2.eggGroups).contains(g));
    }

    /**
     * 检查性别兼容性
     */
    private boolean checkGenderCompatibility(Pokemon p1, Pokemon p2) {
        // 百变怪可与任何非未发现组配对
        if (p1.isDitto || p2.isDitto) return true;

        // 无性别处理
        if (p1.gender == Pokemon.Gender.GENDERLESS ||
                p2.gender == Pokemon.Gender.GENDERLESS) {
            return p1.gender == p2.gender;
        }

        // 常规性别检查
        return p1.gender != p2.gender;
    }
    // endregion

    // region 遗传逻辑
    /**
     * 个体值遗传（核心算法）
     */
    private void inheritIVs(Pokemon baby, Pokemon p1, Pokemon p2) {
        IncubationItems p1_items = p1.getHeldItems();
        IncubationItems p2_items = p2.getHeldItems();

        // 如果父母一方携带了“红线”道具，那么子代将会随机遗传亲代双方的6项个体值中的5项
        int inheritCount = (p1_items.destinyKnot || p2_items.destinyKnot) ? 5 : 3;

        List<Integer> stats = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5));
        List<Integer> inherited = new ArrayList<>();

        // 处理力量道具
        if (p1_items.powerItem || p2_items.powerItem) {
            // 判断谁有力量道具，如果都有随机选择
            if (p1_items.powerItem && p2_items.powerItem) {
                baby.IVs[1] = rand.nextBoolean() ? p1.IVs[1] : p2.IVs[1];
            } else {
                baby.IVs[1] = p1_items.powerItem ? p1.IVs[1] : p2.IVs[1];
            }
            inherited.add(1);
            stats.remove((Integer) 1);
            inheritCount--;
        }

        // 随机选择遗传项
        for (int i = 0; i < inheritCount; i++) {
            int stat = stats.remove(rand.nextInt(stats.size()));
            inherited.add(stat);

            // 判断谁带了红线
            if (p1_items.destinyKnot && p2_items.destinyKnot) { // 如果双方都带了红线
                baby.IVs[stat] = rand.nextBoolean() ? p1.IVs[stat] : p2.IVs[stat];
            } else if (p1_items.destinyKnot) { // 如果只有父亲带了红线
                baby.IVs[stat] = p1.IVs[stat];
            } else { // 如果只有母亲带了红线
                baby.IVs[stat] = p2.IVs[stat];
            }
        }

        // 填充剩余项
        for (int i = 0; i < 6; i++) {
            if (!inherited.contains(i)) {
                baby.IVs[i] = rand.nextInt(32); // 个体值范围是0到31
            }
        }
    }

    /**
     * 性格遗传逻辑
     */
    private void inheritNature(Pokemon baby, Pokemon p1, Pokemon p2) {
        IncubationItems p1_items = p1.getHeldItems();
        IncubationItems p2_items = p2.getHeldItems();

        // 检查是否父母双方都携带了不变石
        boolean bothHaveEverstone = p1_items.everstone && p2_items.everstone;

        // 如果父母双方都携带不变石，则随机选择一方的性格遗传给子代
        if (bothHaveEverstone) {
            baby.nature = rand.nextBoolean() ? p1.nature : p2.nature;
        }
        // 如果仅有一方携带不变石，则子代的性格继承该方的性格
        else if (p1_items.everstone || p2_items.everstone) {
            baby.nature = p1_items.everstone ? p1.nature : p2.nature;
        }
        // 如果父母双方都没有携带不变石，则随机选择父亲或母亲的性格遗传给子代
        else {
            baby.nature = rand.nextBoolean() ? p1.nature : p2.nature;
        }
    }

    /**
     * 特性遗传逻辑
     */
    private void inheritAbility(Pokemon baby, Pokemon p1, Pokemon p2) {

        // 获取母亲宝可梦
        Pokemon mother = getMother(p1, p2);
        Pokemon father = (mother == p1) ? p2 : p1;

        // 如果母亲有隐藏特性
        if (mother != null && mother.hasHiddenAbility) {
            // 子代有60%的概率继承母亲的隐藏特性
            double dist = rand.nextDouble();
            System.out.println(dist);
            baby.hasHiddenAbility = dist < 0.6;
        }
        // 如果母亲没有隐藏特性但父亲有隐藏特性
        else if (father != null && father.hasHiddenAbility) {
            // 子代有40%的概率继承父亲的隐藏特性
            baby.hasHiddenAbility = rand.nextDouble() < 0.4;
        }
        // 如果父母都没有隐藏特性
        else {
            // 普通特性的遗传
            if (mother != null && !mother.hasHiddenAbility) {
                // 母方有80%的概率将其普通特性遗传给子代
                baby.hasHiddenAbility = false; // 默认不继承隐藏特性

                // 如果母亲是百变怪，这种情况已经在getMother中排除
            }
            // 如果母亲为非百变怪且无隐藏特性，则处理父方的情况
            else {
                // 父方为百变怪时，子代有20%的概率获得隐藏特性
                if (father.isDitto) {
                    baby.hasHiddenAbility = rand.nextDouble() < 0.2;
                }
                // 父方为普通特性宝可梦时，子代有40%的概率获得隐藏特性
                else if (!father.hasHiddenAbility) {
                    baby.hasHiddenAbility = rand.nextDouble() < 0.4;
                }
                // 如果都不满足上述条件，默认不继承隐藏特性
                else {
                    baby.hasHiddenAbility = false;
                }
            }
        }
    }

    /**
     * 球种遗传逻辑
     */
    private void inheritBall(Pokemon baby, Pokemon p1, Pokemon p2) {
        Pokemon mother = getMother(p1, p2);
        if (mother != null) {
            baby.ballType = mother.ballType;
        } else if (p1.isDitto) {
            baby.ballType = p2.ballType;
        } else if (p2.isDitto) {
            baby.ballType = p1.ballType;
        } else {
            baby.ballType = rand.nextBoolean() ? p1.ballType : p2.ballType;
        }
    }
    // endregion

    // region 辅助方法
    /**
     * 获取母亲宝可梦（判断百变怪情况）
     */
    private Pokemon getMother(Pokemon p1, Pokemon p2) {

        if (p1.isDitto) return p2.gender == Pokemon.Gender.FEMALE ? p2 : p1;
        if (p2.isDitto) return p1.gender == Pokemon.Gender.FEMALE ? p1 : p2;
        return p1.gender == Pokemon.Gender.FEMALE ? p1 :
                (p2.gender == Pokemon.Gender.FEMALE ? p2 : null);
    }

    /**
     * 计算闪光概率（使用多次判定法）
     */
    private boolean calculateShiny(Pokemon p1, Pokemon p2) {
        IncubationItems p1_items=p1.getHeldItems();
        IncubationItems p2_items=p2.getHeldItems();
        IncubationItems items=p1_items.shinyCharm||p2_items.shinyCharm?p1_items.shinyCharm?p1_items:p2_items:p1_items;
        int rolls = 1;
        // 国际孵蛋加成
        if (!p1.language.equals(p2.language)) rolls += 5;
        // 闪耀护符加成
        if (items.shinyCharm) rolls += 2;

        for (int i = 0; i < rolls; i++) {
            if (rand.nextDouble() < BASE_SHINY_RATE) {
                return true;
            }
        }
        return false;
    }

    /**
     * 计算孵化所需步数
     */
    private int calculateSteps(Pokemon p1, Pokemon p2) {

        IncubationItems p1_items=p1.getHeldItems();
        IncubationItems p2_items=p2.getHeldItems();
        IncubationItems items=p1_items.incense||p2_items.incense?p1_items.incense?p1_items:p2_items:p1_items;

        int base = 256 + rand.nextInt(3585); // 基础步数
        // 火焰之躯特性检查（这里需要扩展）
        return items.incense ? (int)(base * 0.8) : base;
    }
    // endregion

    // 其他方法实现（遗传招式、形态判断等）...
    //形态系统实现
    private String determineForm(Pokemon p1, Pokemon p2) {
        IncubationItems p1_items=p1.getHeldItems();
        IncubationItems p2_items=p2.getHeldItems();
        IncubationItems items=p1_items.incense||p2_items.incense?p1_items.incense?p1_items:p2_items:p1_items;
        // 检测熏香道具
        if (items.incense) {
            if (p1.species.equals("Marill")) return "Azurill";
            // 其他形态判断...
        }
        return p1.form; // 默认继承母亲形态
    }

    //招式遗传增强：
    private List<String> inheritMoves(Pokemon p1, Pokemon p2) {
        List<String> moves = new ArrayList<>();
        // 添加双方蛋招式
        moves.addAll(p1.eggMoves);
        moves.addAll(p2.eggMoves);
        // 去重并随机选择4个
        return moves.stream().distinct()
                .limit(4).collect(Collectors.toList());
    }
//火焰之躯特性支持
//    private int calculateSteps(Pokemon parent, IncubationItems items) {
//        int base = 256 + rand.nextInt(3585);
//        boolean flameBody = parent.ability.equals("Flame Body");
//        return (flameBody || items.flameBody) ? base/2 : base;
//    }

}
